Docker Basics for Spring Boot Applications
What is Docker?โ
Docker is a containerization platform that packages applications and their dependencies into lightweight, portable containers. For Spring Boot applications, Docker provides consistent deployment environments across development, testing, and production.
Core Docker Conceptsโ
Imagesโ
- Definition: Read-only templates used to create containers
- Spring Boot Context: Contains your JAR file, JVM, and runtime dependencies
- Example:
openjdk:17-jre-slimas base image for Spring Boot apps
Containersโ
- Definition: Running instances of Docker images
- Spring Boot Context: Your application running in an isolated environment
- Lifecycle: Created, started, stopped, and removed
Dockerfileโ
- Definition: Text file with instructions to build Docker images
- Purpose: Automates the image creation process
Essential Dockerfile for Spring Bootโ
Basic Dockerfile Structureโ
# Use official OpenJDK runtime as base image
FROM openjdk:17-jre-slim
# Set working directory inside container
WORKDIR /app
# Copy the JAR file into container
COPY target/myapp-1.0.0.jar app.jar
# Expose the port Spring Boot runs on
EXPOSE 8080
# Command to run the application
ENTRYPOINT ["java", "-jar", "app.jar"]
Multi-Stage Build Dockerfile (Recommended)โ
# Build stage
FROM maven:3.8.4-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# Runtime stage
FROM openjdk:17-jre-slim
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Optimized Dockerfile with Layersโ
FROM openjdk:17-jre-slim
# Create non-root user for security
RUN groupadd -r spring && useradd -r -g spring spring
WORKDIR /app
# Copy dependencies first (better caching)
COPY target/dependency/ ./
COPY target/classes ./classes/
COPY target/*.jar app.jar
# Change ownership to spring user
RUN chown -R spring:spring /app
USER spring
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-cp", "/app/classes:/app/dependency/*", "com.example.Application"]
Essential Docker Commandsโ
Image Operationsโ
# Build image from Dockerfile
docker build -t myapp:latest .
# List images
docker images
# Remove image
docker rmi myapp:latest
# Pull image from registry
docker pull openjdk:17-jre-slim
Container Operationsโ
# Run container
docker run -p 8080:8080 myapp:latest
# Run in detached mode
docker run -d -p 8080:8080 --name myapp-container myapp:latest
# List running containers
docker ps
# List all containers
docker ps -a
# Stop container
docker stop myapp-container
# Remove container
docker rm myapp-container
# Execute command in running container
docker exec -it myapp-container bash
Development Commandsโ
# Run with environment variables
docker run -p 8080:8080 -e SPRING_PROFILES_ACTIVE=dev myapp:latest
# Mount volume for logs
docker run -p 8080:8080 -v $(pwd)/logs:/app/logs myapp:latest
# Run with network
docker run -p 8080:8080 --network mynetwork myapp:latest
Docker Compose for Spring Bootโ
Basic docker-compose.ymlโ
version: '3.8'
services:
app:
build: .
ports:
- '8080:8080'
environment:
- SPRING_PROFILES_ACTIVE=docker
depends_on:
- database
networks:
- app-network
database:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- '5432:5432'
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
volumes:
postgres_data:
networks:
app-network:
driver: bridge
Development-Focused docker-compose.ymlโ
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- '8080:8080'
- '5005:5005' # Debug port
environment:
- SPRING_PROFILES_ACTIVE=dev
- JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
volumes:
- .:/app
- /app/target
depends_on:
- database
- redis
database:
image: postgres:13
environment:
POSTGRES_DB: myapp_dev
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev123
ports:
- '5432:5432'
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:7-alpine
ports:
- '6379:6379'
Spring Boot Docker Integrationโ
Application Properties for Dockerโ
# application-docker.properties
spring.datasource.url=jdbc:postgresql://database:5432/myapp
spring.datasource.username=${DB_USER:user}
spring.datasource.password=${DB_PASSWORD:password}
# Redis configuration
spring.redis.host=redis
spring.redis.port=6379
# Actuator for health checks
management.endpoints.web.exposure.include=health,info
management.endpoint.health.show-details=always
Maven Configurationโ
Add to pom.xml:
<properties>
<docker.image.name>myapp</docker.image.name>
</properties>
<build>
<plugins>
<!-- Spring Boot Maven Plugin -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>${docker.image.name}:${project.version}</name>
</image>
</configuration>
</plugin>
<!-- Docker Maven Plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<configuration>
<repository>${docker.image.name}</repository>
<tag>${project.version}</tag>
</configuration>
</plugin>
</plugins>
</build>